package br.com.abril.job;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.fasterxml.jackson.annotation.JsonIgnore;

import br.com.abril.shared.ApplicationContextProvider;

@Transactional
public abstract class AbstractTask implements Runnable {

	private final Logger logger = Logger.getLogger(this.getClass());

	protected Job job;

	private JobRepository repository;

	protected ApplicationContext applicationContext;

	public AbstractTask() {

		applicationContext = ApplicationContextProvider.getApplicationContext();

		repository = applicationContext.getBean(JobRepository.class);
	}

	@Override
	public void run() {

		logger.info(".................. Starting Job");
		try {

			preAction();

			execute();

		} catch (Exception e) {
			logger.error("Job Exception [" + job + " ] ", e);
			job.setStatus(Job.StatusType.TERMINATED_WITH_ERROR);	
		} finally {
			posAction();
		}
		logger.info(".................. End Job");

	}

	@Transactional(propagation = Propagation.REQUIRED)
	public abstract void execute();

	@Transactional(propagation = Propagation.NESTED)
	public void preAction() {
		job.startingJobNow();
		store(job);
	}

	@Transactional(propagation = Propagation.NESTED)
	public void posAction() {
		job.endJobNow();
		store(job);
	}

	@Transactional
	public void store(Job job) {
		repository.save(job);
	}

	@JsonIgnore
	public Job getJob() {
		return job;
	}

	public void setJob(Job job) {
		this.job = job;
	}

}